Java基础知识(十五)
扩展概念
匿名内部类
interface Message {
public void print();
}
class Messagelmpl implements Message {
public void print() {
System.out.println("Hello");
}
}
public class Demo {
public static void main(String[] args) {
fun(new Messagelmpl());
}
public static void fun(Message msg) {
msg.print();
}
}
假如Messagelmpl
只使用一次,那么就可以利用匿名内部类。
范例:使用匿名内部类
interface Message {
public void print();
}
public class Demo {
public static void main(String[] args) {
fun(new Message() {
// 匿名内部类
public void print() {
System.out.println("Hello");
}
});
}
public static void fun(Message msg) {
msg.print();
}
}
使用匿名内部类的前提:必须基于接口或抽象类的应用。
匿名内部类定义在方法中,方法的参数或是变量要被匿名内部类访问,必须加上final
关键字。匿名内部类的优点在于减少了类的定义。
基本数据类型的包装类
1、Java设计的基本原则:一切皆对象,一切操作都以对象的形式进行描述。此时我们发现,有一个矛盾点,基本数据类型不是对象。对于这个矛盾点,我们可以进行处理:
class MyInt { // 定义类
private int num; // 类封装基本数据类型
// 定义构造方法,将基本数据类型传递给对象
public MyInt(int num) {
this.num = num;
}
public int intValue() { // 返回被封装的数据
return this.num;
}
}
public class Demo {
public static void main(String[] args) {
MyInt mi = new MyInt(10); // 装箱
int temp = mi.intValue(); // 拆箱
// 被封装的数据只有拆箱后才能进行计算
System.out.println(temp * 2);
}
}
Java为了方便用户使用,专门提供了一组包装类,来包装所有的基本类型:byte(Byte)
、short(Short)
、int(Integer)
、long(Long)
、float(Float)
、double(Double)
、boolean(Boolean)
、char(Character)
。()中为基本类型对应的包装类。
以上包装类严格讲分为两种子类型:
· 对象型包装类(Object直接子类):Character,Boolean;
· 数值型包装类(Number直接子类):Byte、Short、Integer、Float、Long、Double
Numbe
是一个抽象类,一共定义了六个操作方法:byteValue()
、shortValue()
、integerValue()
、floatValue()
、longValue()
、doubleValue()
。
装箱与拆箱
1、基本数据类型与包装类间的转换通过以下方式:
· 装箱操作: 将基本数据类型变为包装类的形式:
|- 每个包装类的构造方法都可以接收各自数据类型的变量;
· 拆箱操作: 将包装类取出被包装基本数据类型数据:
|- 利用Number类中提供的一些列xxValue()方法
范例:使用int和Integer
public class Demo {
public static void main(String[] args) {
Integer obj = new Integer(10); // 装箱
int temp = obj.intValue(); // 拆箱
System.out.println(temp * 2);
}
}
范例:使用double和Double
public class Demo {
public static void main(String[] args) {
Double obj = new Double(10.2); // 装箱
double temp = obj.doubleValue(); // 拆箱
System.out.println(temp * 2);
}
}
范例:使用boolean和Boolean
public class Demo {
public static void main(String[] args) {
Boolean obj = new Boolean(true); // 装箱
boolean temp = obj.booleanValue(); // 拆箱
System.out.println(!temp);
}
}
2、所有包装类都利用同种格式的方法进行操作。但在JDK1.5之后,增加了自动装箱和自动拆箱的机制,并且可以直接使用包装类的对象进行数字计算,为开发提供了便利。
public class Demo {
public static void main(String[] args) {
Integer obj = 10; // 自动装箱
int temp = obj; // 自动拆箱
obj++; // 包装类直接进行数学计算
System.out.println(temp * obj);
}
}
3、注意点:Integer对象可以直接赋值,也可以使用构造方法赋值,二者有何区别?
两者的区别可以参考String类直接赋值和构造方法赋值的区别。
public class Demo {
public static void main(String[] args) {
Integer objA = 10; // 自动装箱
Integer objB = 10; // 自动装箱
Integer objC = new Integer(10);
System.out.println(objA == objB); // true
System.out.println(objA == objC); // false
System.out.println(objA.equals(objC)); // true
}
}
使用包装类时,几乎都是直接赋值,很少使用构造方法,判断内容是否相等时依然使用equals()
方法。
4、Object类可以接收一切引用数据类型,由于自动装箱机制的存在,Object也可以接收基本数据类型。
流程:基本数据类型 → 自动装箱(成为对象) → 向上转型为Object。
public class Demo {
public static void main(String[] args) {
Object obj = 10;
// Object不能直接向下转型向int
// Object只能自动转型为Integer
int temp = (Integer) obj;
System.out.println(temp * 2);
}
}
数据类型转换
1、包装类多用于数据类型转换:在包装类中提供了将String数据变为基本数据类型的方法。
如下:
· Integer类:public static int parseInt(String s);
· Double类:public static double parseDouble(String s);
· Boolean类:public static boolean parseBoolean(String s);
注意:Character
类不存在将字符串变为字符的方法,但String
类的charAt()
可以根据索引取出字符。
范例:将String变为int型
public class Demo {
public static void main(String[] args) {
String str = "123";
int temp = Integer.parseInt(str);
System.out.println(temp * 2);
}
}
将字符串变为int型的前提是:该字符串全部为数字.
范例:将String变为double型
public class Demo {
public static void main(String[] args) {
String str = "12.3";
double temp = Double.parseDouble(str);
System.out.println(temp * 2);
}
}
范例:将String变为boolean
public class Demo {
public static void main(String[] args) {
String str = "true";
boolean temp = Boolean.parseBoolean(str);
System.out.println(!temp);
}
}
Boolean转换时,如果字符串的值不是true或false,默认转为false。
2、字符串可以变为基本数据类型,基本数据类型也可变为字符串。方法有两种:
(1)任何基本数据类型与字符串使用+
连接后,都会变为String类型数据
public class Demo {
public static void main(String[] args) {
int num = 100;
String str = num + ""; // 变为String类
System.out.println(str.replaceAll("0", "9")); // 199
}
}
上述方式虽然完成了转换,但产生了垃圾""
(2)利用public static String valueOf(数据类型 变量)
public class Demo {
public static void main(String[] args) {
int num = 100;
String str = String.valueOf(num);
System.out.println(str.replaceAll("0", "9")); // 199
}
}
上述方式不会产生垃圾,因此开发中常用上述方法。
包的定义及使用
包的定义
1、包指的是程序的目录。早期开发一个程序是将所有类写在一个java文件中,编译后程序将直接保存在根目录下。利用包可以实现程序拆分,将不同的类根据要求保存在不同目录中。
包的定义通过关键字package
完成。
范例:定义包
package com.java.demo;
public class Demo {
public static void main(String[] args) {
}
}
2、定义包时用.
表示子目录。如果类中有包的定义,就必须使其保存在对应的目录下,而这些目录不需要手动创建,可以使用命令自动生成:
(1)打包编译:java -d . Demo.java
|- -d
: 根据package
定义生成目录;
|-.
:设置保存路径。.
表示在当前路径下生成。
(2)解释程序时不要进入包中解释程序,而是在包外输入类的完整名称包.类
:
|- java com.java.demo.Demo
包的导入
1、使用包可以将一个完整的程序拆分为不同文件,从而分别保存。这存在问题:不同包间可能要进行互相访问,就需要进行导包操作,使用import
语句完成。
范例:定义com.java.util.Message
package com.java.util;
class Message{
public static void print(){
System.out.println("Hello World !");
}
}
定义com.java.test.TestMessage
package com.java.test;
import com.java..util.Message;
public class TestMessage {
public static void print() {
Message msg = new Message();
msg.print();
}
}
编译时,应先编译Message,再编译TestMessage:
|- javac -d . Message.java
|- javac -d . TestMessage.java
此时报错:Message在com.java.util中不是公共的; 无法从外部程序包中对其进行访问
出现上述问题是因为public class定义的类可以被不同的包访问;而class定义的类只能被本包所访问。因此我们要修改Message.java:
package com.java.util;
public class Message{
public static void print(){
System.out.println("Hello World !");
}
}
Java编译器考虑到大型程序开发,因此可以使用通配符*
:java -d . *.java
编译当前目录下所有java文件。
2、当要导入一个包中多个类时,可以使用import 包.*
package com.java.test;
import com.java..util.*;
public class TestMessage {
public static void print() {
Message msg = new Message();
msg.print();
}
}
import 包.*
并不是导入包中所有的类,而是只导入程序所需的类,因此不用担心性能问题。
3、一个Java文件可能导入多个包,而不同包中可能存在同名的类。现假设:
·com.java.util.Message;
·com.java.demo.Message.
package com.java.demo;
public class Message {
public static void print() {
System.out.println("世界你好!");
}
}
由于需要,要同时导入上述两个类:
package com.java.test;
import com.java.demo.Message;
import com.java.util.Message;
public class TestMessage {
public static void main(String[] args) {
Message msg = new Message();
msg.print();
}
}
系统报错:Error:(4, 1) java: com.java.demo.Message的 single-type-import 已定义具有相同简名的类型。
为了避免该错误,在使用类时,应加上包名:
package com.java.test;
import com.java.demo.Message;
import com.java.util.Message;
public class TestMessage {
public static void main(String[] args) {
com.java.demo.Message msg = new com.java.demo.Message();
Message.print();
}
}
系统常用包
Java提供了许多程序开发包,此外还有许多第三方包。Java自带的常见系统包如下:
(1)java.lang:包含了String、Object、Integer等类,此包系统自动导入;
(2)java.lang.reflect:反射开发包;
(3)java.util:Java的工具包,提供了大量的工具类,像链表;
(4)java.util.regex:正则工具包;
(5)java.text:国际化处理程序包;
(6)java.io:进行输入、输出处理以及文件操作;
(7)java.net:网络编程开发包;
(8)java.sql:数据库程序开发包;
(9)java.applet:Applet程序开发包(已经不用了);
|-Applet指的是在网页上嵌套的程序,可以使用Applet做一些动态效果,是采用绘图的方式完成的显示。随着时间的发展,Applet程序已经不再使用了(如果要再实现同样的功能,都是用Canvas绘图)。
(10)java.awt、javax.swing:图形界面的开发包,主要功能是开发单机程序界面。
|-JDK1.0时推出了awt开发包,但是这个开发包使用了大量的windows图形函数,使Java丧失了可移植性;
|-JDK1.2时推出了javax.swing开发包,是一个轻量级(Java自己开发的,不再使用windows),所以Java更名为Java2;
jar命令
使用jar命令压缩class文件,压缩的单位为包。
范例:定义Message.java文件
package com.java.util;
class Message{
public static void print(){
System.out.println("Hello World !");
}
}
编译后会生成class文件,此时要交付给用户使用,将改包的代码压缩:jar -cvf my.jar com
。生成的jar文件不能直接使用,必须配置CLASSPATH才能使用:SET CLASSPATH = .;jar包所在路径
。开发中需要使用大量的第三方jar文件,都需要配置CLASSPATH,最简单的配置就是在环境变量中配置。
This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(十五)/